package com.scwuhua.service.impl;



import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.MeteorologicalSoilConstants;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.enumCode.ErrorCode;
import com.ruoyi.common.utils.AssertUtil;
import com.ruoyi.common.utils.StringUtils;
import com.scwuhua.domain.Device;
import com.scwuhua.dto.GainTokenDto;
import com.scwuhua.dto.IntegratedData;
import com.scwuhua.dto.MeteorologicalSoilListDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.scwuhua.mapper.MeteorologicalSoilMapper;
import com.scwuhua.domain.MeteorologicalSoil;
import com.scwuhua.service.IMeteorologicalSoilService;
import org.springframework.web.client.RestTemplate;

/**
 * 数据查询Service业务层处理
 * 
 * @author wuhua
 * @date 2023-05-06
 */

@Slf4j
@Service
public class MeteorologicalSoilServiceImpl implements IMeteorologicalSoilService 
{
    @Autowired
    private MeteorologicalSoilMapper meteorologicalSoilMapper;
    @Autowired
    private DeviceServiceImpl deviceServiceImpl;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Value("${MeteorologicalSoil.authentication.username}")
    private String username;
    @Value("${MeteorologicalSoil.authentication.password}")
    private String password;
    @Value("${MeteorologicalSoil.authentication.loginUrl}")
    private String loginUrl;
    @Value("${MeteorologicalSoil.pagingData.listUrl}")
    private String listUrl;
    @Value("${MeteorologicalSoil.pagingData.countUrl}")
    private String countUrl;

    /**
     * 查询数据查询列表
     * 
     * @param meteorologicalSoil 数据查询
     * @return 数据查询
     */
    @Override
    public IntegratedData selectMeteorologicalSoilList(MeteorologicalSoil meteorologicalSoil)
    {
        /*判断是否获取到token
        * 没有就重新获取
        * */
        String loginToken = gainToken();
        /*
        * 拿到前端传来的页数与每页条数
        *   时间节点
        *   设备编号
        * */
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        Integer facId = meteorologicalSoil.getFacId();
        String endDataTime = meteorologicalSoil.getEndDataTime();
        String beginDataTime = meteorologicalSoil.getBeginDataTime();
        //log.info( meteorologicalSoil.getEndDataTime()+"======="+meteorologicalSoil.getFacId()+"========"+meteorologicalSoil.getBeginDataTime());
        String url  = null;
        url = listUrl+facId+"?&pageNum="+ pageNum +"&pageSize="+ pageSize +"&endTime="+endDataTime+"&startTime="+beginDataTime;

        /*发送http请求api接口
        *   1.获取数据
        *   2.获取条数
        *  数据封装为data
        */
        String body = sendGetRequest(loginToken,url);
        List<MeteorologicalSoilListDto> meteorologicalSoils = JSONArray.parseArray(body, MeteorologicalSoilListDto.class);
        log.info("loginToken============="+loginToken);
        url = countUrl+facId+"/count"+"?&pageNum="+ pageNum +"&pageSize="+ pageSize +"&endTime="+endDataTime+"&startTime="+beginDataTime;
        log.info(url);
        body = sendGetRequest(loginToken,url);

        IntegratedData integratedData = new IntegratedData();
        integratedData.setMeteorologicalSoilListData(meteorologicalSoils);
        integratedData.setTotal(Integer.parseInt(body));
        //数据库查询走下面
       /*List<MeteorologicalSoil> meteorologicalSoils = meteorologicalSoilMapper.selectMeteorologicalSoilList(meteorologicalSoil);
       log.info("22222222222222222222222"+meteorologicalSoils.toString());*/
        return integratedData;
    }

    public String sendGetRequest(String loginToken,String url) {
        /*
        * 发起HTTP请求api接口
        *  get请求
        *  添加请求头，url参数 返回类型设为String
        *  获取到响应体，转换为list集合
        *  发送第二条http请求，获取total
        *  整合数据和条数，返回Data数据
        * */
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.add(MeteorologicalSoilConstants.SPECIFIED_TYPE, MeteorologicalSoilConstants.RETURN_JSON);
        headers.add("token", loginToken);
        HttpEntity<String> formEntity = new HttpEntity<>(headers);
        ResponseEntity<String> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                formEntity,
                String.class
        );
        return response.getBody();
    }

    /*
    *  认证 - token获取
    *   每次请求三方接口要携带获取到的token一起传输
    * */
    public String gainToken(){
            if (StringUtils.isEmpty(redisTemplate.boundValueOps(MeteorologicalSoilConstants.M_TOKEN_KEY).get())){
                RestTemplate restTemplate = new RestTemplate();
                HttpHeaders headers = new HttpHeaders();
                //添加请求头
                headers.add(MeteorologicalSoilConstants.SPECIFIED_TYPE, MeteorologicalSoilConstants.RETURN_JSON);
                //添加请求体
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(MeteorologicalSoilConstants.USER_NAME,username);
                jsonObject.put(MeteorologicalSoilConstants.PASS_WORD,password);
                //组装请求参数
                HttpEntity<String> formEntity = new HttpEntity<String>(net.minidev.json.JSONObject.toJSONString(jsonObject),headers);
                ResponseEntity<GainTokenDto> response = restTemplate.exchange(
                        loginUrl,//获取资源的地址 //请求路径
                        HttpMethod.POST,
                        formEntity,
                        GainTokenDto.class//返回类型
                );
                String token = Objects.requireNonNull(response.getBody()).getToken();
                Integer expiration = response.getBody().getExpiration();
                AssertUtil.isNotEmpty(token,ErrorCode.TOKEN_ACQUISITION_FAILURE.getMessage());
                log.info("认证成功，获取到token");
                redisTemplate.boundValueOps(MeteorologicalSoilConstants.M_TOKEN_KEY).set(token,expiration-300, TimeUnit.SECONDS);
            }
        return redisTemplate.boundValueOps(MeteorologicalSoilConstants.M_TOKEN_KEY).get();
    }


    /**
     * 查询设备当日数据
     * */
    @Override
    public List<MeteorologicalSoil> dayData(MeteorologicalSoil meteorologicalSoil) {
        /*判断是否存在token* */
        String token = gainToken();
        Integer facId = meteorologicalSoil.getFacId();
        /*发送http请求*/
        String  url = "http://47.105.215.208:8005/todaydata/"+facId;
        String body = sendGetRequest(token, url);
        List<MeteorologicalSoil> meteorologicalSoils = JSONArray.parseArray(body, MeteorologicalSoil.class);
        log.info("设备当日数据"+meteorologicalSoil);
        return meteorologicalSoils;
    }

    /**
     * 查询设备最新数据
     * */
    @Override
    public MeteorologicalSoilListDto newestData(MeteorologicalSoil meteorologicalSoil) {
        /*
        *   校验token
        *   发送http请求
        * */
        String token = gainToken();
        Integer facId = meteorologicalSoil.getFacId();
        String url = "http://47.105.215.208:8005/data/"+facId;
        String body = sendGetRequest(token, url);
        return JSONObject.parseObject(body, MeteorologicalSoilListDto.class);
    }

    /**
     * 一键同步功能
     * */
    @Override
    public int synchroData() {
        /*
        * 查出所有的设备
        * 用设备id查出所有数据
        * 将不存在的数据添加到数据库
        * */
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        MeteorologicalSoil ms = new MeteorologicalSoil();
        List<Device> devices = deviceServiceImpl.selectDeviceList();
        AssertUtil.isNotEmpty(devices,ErrorCode.DATA_ACQUISITION_EXCEPTION.getMessage());
        for (Device device : devices) {
            ms.setFacId(device.getFacId());
            //每台设备的分页数据
            /* IntegratedData integratedData = selectMeteorologicalSoilList(ms);*/
            String loginToken = gainToken();
            String url  = null;
            url = listUrl+device.getFacId()+"?&pageNum="+ 1 +"&pageSize="+ 10000;
            String body = sendGetRequest(loginToken, url);
            List<MeteorologicalSoilListDto> meteorologicalSoilListData = JSONArray.parseArray(body, MeteorologicalSoilListDto.class);
            for (MeteorologicalSoilListDto msd : meteorologicalSoilListData) {
                //查数据库
                 ms = meteorologicalSoilMapper.selectMeteorologicalSoilByFacId(msd.getFacId());
                if (ms==null){
                    BeanUtils.copyProperties(msd,ms);
                    try {
                        Date newData = sdf.parse(msd.getDataTime());
                        ms.setDataTime(newData);
                        meteorologicalSoilMapper.insertMeteorologicalSoil(ms);
                    } catch (ParseException e) {
                        e.printStackTrace();
                        log.info("字符和时间类型转换异常");
                    }

                }
            }
        }
        return 0;
    }





    /**
     * 查询数据查询
     *
     * @param id 数据查询主键
     * @return 数据查询
     */
    @Override
    public MeteorologicalSoil selectMeteorologicalSoilById(Integer id)
    {
        return meteorologicalSoilMapper.selectMeteorologicalSoilById(id);
    }

    /**
     * 新增数据查询
     *
     * @param meteorologicalSoil 数据查询
     * @return 结果
     */
    @Override
    public int insertMeteorologicalSoil(MeteorologicalSoil meteorologicalSoil)
    {
        return meteorologicalSoilMapper.insertMeteorologicalSoil(meteorologicalSoil);
    }

    /**
     * 修改数据查询
     *
     * @param meteorologicalSoil 数据查询
     * @return 结果
     */
    @Override
    public int updateMeteorologicalSoil(MeteorologicalSoil meteorologicalSoil)
    {
        return meteorologicalSoilMapper.updateMeteorologicalSoil(meteorologicalSoil);
    }

    /**
     * 批量删除数据查询
     *
     * @param ids 需要删除的数据查询主键
     * @return 结果
     */
    @Override
    public int deleteMeteorologicalSoilByIds(Integer[] ids)
    {
        return meteorologicalSoilMapper.deleteMeteorologicalSoilByIds(ids);
    }

    /**
     * 删除数据查询信息
     *
     * @param id 数据查询主键
     * @return 结果
     */
    @Override
    public int deleteMeteorologicalSoilById(Integer id)
    {
        return meteorologicalSoilMapper.deleteMeteorologicalSoilById(id);
    }

}
